#ifndef __MC_CONTROL_H
#define __MC_CONTROL_H

#include "stdint-gcc.h"
#include "mc_param.h"

#define  MC_NO_ERROR  (uint16_t)(0x0000u)      /**< @brief No error.*/
#define  MC_NO_FAULTS  (uint16_t)(0x0000u)     /**< @brief No error.*/
#define  MC_FOC_DURATION  (uint16_t)(0x0001u)  /**< @brief Error: FOC rate to high.*/
#define  MC_OVER_VOLT  (uint16_t)(0x0002u)     /**< @brief Error: Software over voltage.*/
#define  MC_UNDER_VOLT  (uint16_t)(0x0004u)    /**< @brief Error: Software under voltage.*/
#define  MC_OVER_TEMP  (uint16_t)(0x0008u)     /**< @brief Error: Software over temperature.*/
#define  MC_START_UP  (uint16_t)(0x0010u)      /**< @brief Error: Startup failed.*/
#define  MC_SPEED_FDBK  (uint16_t)(0x0020u)    /**< @brief Error: Speed feedback.*/
#define  MC_BREAK_IN  (uint16_t)(0x0040u)      /**< @brief Error: Emergency input (Over current).*/
#define  MC_SW_ERROR  (uint16_t)(0x0080u)      /**< @brief Software Error.*/
#define  TIM_MAX_DUTY_CNT 3600U
#define  TIM_DUTY_DEAD_CNT 100U



typedef enum
{
  PWM_DUTY_OVERFLOW,

}ERROR_CODE;

typedef struct PID_Handle
{
  int16_t   def_kp_gain;            /**< Default @f$K_{pg}@f$ gain */
  int16_t   def_ki_gain;            /**< Default @f$K_{ig}@f$ gain */
  int16_t   kp_gain;                /**< @f$K_{pg}@f$ gain used by PID component */
  int16_t   ki_gain;                /**< @f$K_{ig}@f$ gain used by PID component */
  int32_t   integral_term;          /**< integral term */
  int32_t   upper_integral_limit;   /**< Upper limit used to saturate the integral*/
  int32_t   lower_integral_limit;   /**< Lower limit used to saturate the integral*/
  int16_t   upper_output_limit;     /**< Upper limit used to saturate the PI output */
  int16_t   lower_output_limit;     /**< Lower limit used to saturate the PI output */
  uint16_t  kp_divisor;             /**< Kp gain divisor, used in conjuction */
  uint16_t  ki_divisor;             /**< Ki gain divisor, used in conjuction */
  uint16_t  kp_divisor_pow2;        /**< Kp gain divisor expressed as power of 2.
                                       E.g. if gain divisor is 512 the value
                                       must be 9 as 2^9 = 512 */
  uint16_t  ki_divisor_pow2;        /**< Ki gain divisor expressed as power of 2.
                                       E.g. if gain divisor is 512 the value
                                       must be 9 as 2^9 = 512 */
  int16_t   def_kd_gain;            /**< Default Kd gain */
  int16_t   kd_gain;                /**< Kd gain used by PID component */
  uint16_t  kd_divisor;             /**< Kd gain divisor, used in conjuction */
  uint16_t  kd_divisor_pow2;        /*!< Kd gain divisor expressed as power of 2.
                                       E.g. if gain divisor is 512 the value
                                       must be 9 as 2^9 = 512 */
  int32_t   prev_process_var_error; /*!< previous process variable used by the
                                       derivative part of the PID component */
} PidHandle_t;


uint16_t set_pwm(Motor_t *motor);
void get_speed(Motor_t *motor);
void speed_loop_control(Motor_t *motor);
void low_freq_task(Motor_t *motor);
void get_tres_phase_current(Motor_t *motor);
void set_adc_samp_points(Motor_t *motor);

int16_t pi_controller(PidHandle_t *phandle, int32_t process_var_error);
int16_t pid_controller(PidHandle_t *pHandle, int32_t process_var_error);
void pid_handle_init( PidHandle_t * pHandle );

#endif
